Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lib.network: add ipv6 parser #318712

Merged
merged 3 commits into from
Jul 11, 2024
Merged

Conversation

woojiq
Copy link
Contributor

@woojiq woojiq commented Jun 10, 2024

Description of changes

Mentor: @Janik-Haag

Things done

  • Tested, as applicable:

Add a 👍 reaction to pull requests you find important.

@github-actions github-actions bot added the 6.topic: lib The Nixpkgs function library label Jun 10, 2024
@woojiq woojiq force-pushed the lib-network-ipv6-parser branch from d2bceb3 to 69089c5 Compare June 10, 2024 07:31
@ofborg ofborg bot added 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin 10.rebuild-linux: 1-10 labels Jun 10, 2024
lib/network/default.nix Outdated Show resolved Hide resolved
in
assert lib.asserts.assertMsg (
builtins.length addr == 8
) "_parseNormalized expected to recieve normalized IPv6 address";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
) "_parseNormalized expected to recieve normalized IPv6 address";
) "_parseNormalized expects a normalized IPv6 address";

But what does "normalized" in this case even mean? I don't think the function name matches its purpose well.

lib/network/default.nix Outdated Show resolved Hide resolved
.gitignore Show resolved Hide resolved
lib/trivial.nix Outdated Show resolved Hide resolved
lib/tests/network.sh Outdated Show resolved Hide resolved
lib/tests/network.sh Outdated Show resolved Hide resolved
lib/network/default.nix Outdated Show resolved Hide resolved
lib/network/default.nix Show resolved Hide resolved
lib/network/default.nix Outdated Show resolved Hide resolved
lib/network/default.nix Outdated Show resolved Hide resolved
lib/network/default.nix Outdated Show resolved Hide resolved
@Janik-Haag
Copy link
Member

To address your questions:

Do I need to somehow hide the internal functions more than just underscoring them?

Yes currently they would all get exposed, you have to put them into a let binding to make them truly internal. Take a look at https://github.com/NixOS/nixpkgs/blob/master/lib/fileset/default.nix#L103 as an example.

Are the doc comments in the correct format (already existing files have different style)?

Some of them are some of them aren't, please take a look at the example

Do I need to pull the ipv4 parser implementation to merge them together? #299409

no, we should keep them separate and preferably go for small prs, e.g. once the parser is fine merge this pr and then do another v6 one for cidr related functions.

@woojiq woojiq force-pushed the lib-network-ipv6-parser branch 2 times, most recently from 8ad8940 to 5f1b84c Compare June 22, 2024 11:53
@woojiq woojiq marked this pull request as ready for review June 22, 2024 11:58
@woojiq woojiq requested a review from infinisil as a code owner June 22, 2024 11:58
@woojiq woojiq marked this pull request as draft June 22, 2024 12:00
@woojiq woojiq force-pushed the lib-network-ipv6-parser branch from 5f1b84c to 05c8c7b Compare June 22, 2024 12:19
@woojiq woojiq marked this pull request as ready for review June 22, 2024 12:20
@woojiq
Copy link
Contributor Author

woojiq commented Jun 22, 2024

@Janik-Haag @mweinelt I refactored the code and moved internal functions to internal.nix. Can you review again please?

@woojiq woojiq marked this pull request as draft June 23, 2024 08:36
@woojiq woojiq force-pushed the lib-network-ipv6-parser branch from 05c8c7b to 1ed35a9 Compare June 23, 2024 17:06
@woojiq woojiq marked this pull request as ready for review June 23, 2024 17:08
Copy link
Member

@Janik-Haag Janik-Haag left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is getting into shape. There are some smaller points left to do, and you should add a lot more comments explaining different parts, I think. This part of lib currently is very undocumented internally compared to others like lib.fileset or lib.generators.

lib/network/internal.nix Show resolved Hide resolved
if 1 <= n && n <= ipv6Bits then
n
else
throw "${apiName}: IPv6 subnet should be in range [1;${toString ipv6Bits}], got ${toString n}";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uh, I don't think we want to pass around the function name here, this will only get more confusing to debug because your output would gaslight the user, once other functions rely on the ${apiName} function internally.

Comment on lines 38 to 40
api = "lib.network.ipv6.fromString";

splittedAddr = _ipv6.split api addr;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove the "api" part.

Comment on lines 42 to 48
emptyExpected =
if hasPrefix || hasSuffix then
2
else if hasInfix then
1
else
0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be moved in the same scope as the emptyCount definition

Comment on lines 19 to 21
ipv6Bits = 128;
ipv6Pieces = 8;
ipv6PieceBits = 16;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should link to the corresponding RFC definitions, and maybe write a comment explaining them, since these are magic numbers to anyone unfamiliar with networking.

Comment on lines 62 to 69
let
zeros = genList (_: "0") (ipv6Pieces - piecesNoEmptyLen);
in
if hasPrefix then zeros ++ piecesNoEmpty else piecesNoEmpty ++ zeros
else if hasInfix then
concatMap (
piece: if piece == "" then genList (_: "0") (ipv6Pieces - piecesNoEmptyLen) else [ piece ]
) pieces
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can reuse the zeros variable in line 68 in the concatMap function, because it's doing the same.

Comment on lines 119 to 194
let
splitted = strings.splitString "/" addr;
splittedLength = length splitted;
in
if splittedLength == 1 then # [ ip ]
{
address = parseIpv6FromString apiName addr;
prefixLength = 64; # /64 is a standard size IPv6 subnet as defined by the IETF.
}
else if splittedLength == 2 then # [ ip subnet ]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should be stricter with the user input and don't silently just set some prefix but instead fail saying that it's not a cidr address.
Also, usually the assumption I'm familiar with if you just don't specify a prefix is that you get a /128.

Copy link
Contributor Author

@woojiq woojiq Jun 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, 128 sounds more logical if prefix length is omitted.

I think we should be stricter with the user input and don't silently just set some prefix but instead fail saying that it's not a cidr address.

I added one fromString function and user can use both default and cidr notation. I don't see a reason to create two separate API functions like fromString and fromCidrString, because this can be easily observed from the passed string - if it contains a /, then we try to parse it as cidr notation.

@woojiq woojiq force-pushed the lib-network-ipv6-parser branch from 1ed35a9 to 504a79b Compare June 28, 2024 17:40
woojiq and others added 2 commits June 28, 2024 20:53
Co-authored-by: lucasew <lucas59356@gmail.com>
@woojiq woojiq force-pushed the lib-network-ipv6-parser branch from 504a79b to 9a035ac Compare June 28, 2024 17:54
Add a library function to parse and validate an IPv6 address from a
string. It can parse the first two versions of an IPv6 address according
to https://datatracker.ietf.org/doc/html/rfc4291#section-2.2. The third
form "x:x:x:x:x:x.d.d.d.d" is not yet implemented. Optionally parser can accept prefix length (128 is default).

Add shell script network.sh to test IPv6 parser functionality.
@woojiq woojiq force-pushed the lib-network-ipv6-parser branch from 9a035ac to d559eed Compare June 29, 2024 07:02
Copy link
Member

@Janik-Haag Janik-Haag left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@infinisil as a lib code owner, do you want to give this a review before we merge it?

lib/network/default.nix Show resolved Hide resolved
@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/showcase-nixpkgs-network-library/48897/1

@Janik-Haag Janik-Haag merged commit c20399e into NixOS:master Jul 11, 2024
21 checks passed
@woojiq woojiq deleted the lib-network-ipv6-parser branch July 11, 2024 19:00
@woojiq woojiq mentioned this pull request Jul 13, 2024
13 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
6.topic: lib The Nixpkgs function library 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin 10.rebuild-linux: 1-10
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants